package ifgi.potwc.ipt.ui;

import ifgi.potwc.ipt.R;
import ifgi.potwc.ipt.sensor.IptSensorService;
import ifgi.potwc.ipt.store.Store;
import ifgi.potwc.ipt.upload.IptUploadService;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockActivity;

/**
 * This class is the main UI and handles all user interaction except settings.
 * 
 * @author saschak.
 */
public class MainActivity extends SherlockActivity
{
    private static final int SETTINGS = 21;
    private static final int CHECK_FEED_ID = 43;

    // Context
    private Context ctx;

    // SharedPreferences
    private static SharedPreferences prefs;
    private Editor editor;

    // EditText for entering the feed_id
    private EditText editText;

    // Button
    private Button startButton;

    // For checking network provider status
    private LocationManager locManager;
    private boolean networkEnabled = false;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.layout_main);

	// Initialize attributes
	ctx = getApplicationContext();
	prefs = SettingsActivity.getPrefs(this);
	editor = prefs.edit();
	locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

	// EditText
	editText = (EditText) findViewById(R.id.feedIdEdit);

	// Button
	startButton = (Button) findViewById(R.id.startButton);
	changeButtonLayout(); // Initialize button layout
	startButton.setOnClickListener(new View.OnClickListener()
	{
	    @SuppressWarnings("deprecation")
	    @Override
	    public void onClick(View v)
	    {
		// Check if locating via network is enabled
		networkEnabled = locManager
			.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

		if (!networkEnabled)
		{
		    Toast.makeText(ctx, R.string.networkDisabled,
			    Toast.LENGTH_LONG).show();

		    startActivity(new Intent(
			    Settings.ACTION_LOCATION_SOURCE_SETTINGS));
		}
		else
		{

		    if (!isTracking())
		    {
			// The Feed ID
			String feedID = editText.getText().toString();

			// If the Feed ID is empty...
			if (feedID.equals(""))
			{
			    // Inform the user to enter a Feed ID
			    Toast.makeText(ctx, R.string.noFeedID,
				    Toast.LENGTH_SHORT).show();
			}
			else
			{
			    // Dismiss the keyboard
			    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
			    imm.hideSoftInputFromWindow(
				    editText.getWindowToken(), 0);

			    // Show the Check Feed ID Dialog
			    showDialog(CHECK_FEED_ID);
			}
		    }
		    else
		    {
			manageWorkflow();
		    }
		}
	    }
	});
    }
    
    @Override
    protected void onPause()
    {
	// Save editText entry
	String text = editText.getText().toString();
	editor.putString("editText", text);
	editor.commit();
	
	super.onPause();
    }

    @Override
    protected void onResume()
    {
	super.onResume();

	if(!isTracking())
	{
	    editText.setText(prefs.getString("editText", ""));
	}
	else
	{
	    // Show the current Feed ID in the EditText
	    String feedID = prefs.getString(Store.FEED_ID, "");
	    editText.setText(feedID);
	}
    }

    // ***************************************************************************
    // Dialog

    @SuppressWarnings("deprecation")
    @Override
    protected Dialog onCreateDialog(int id)
    {
	switch (id)
	{
	case CHECK_FEED_ID:
	    // Create Check FeedID Dialog
	    Builder builder = new AlertDialog.Builder(this);
	    builder.setMessage("Please check if "
		    + editText.getText().toString()
		    + " is the correct feed ID for your parcel tracking process.");
	    builder.setCancelable(true);
	    builder.setPositiveButton("OK", new OkOnClickListener());
	    builder.setNegativeButton("Cancel", new CancelOnClickListener());
	    AlertDialog dialog = builder.create();
	    dialog.show();
	}
	return super.onCreateDialog(id);
    }

    /**
     * OnClickListener for the Check Feed ID Dialog's Cancel-Button.
     * 
     * @author saschak.
     */
    private final class CancelOnClickListener implements
	    DialogInterface.OnClickListener
    {
	public void onClick(DialogInterface dialog, int which)
	{
	    // Do nothing
	}
    }

    /**
     * OnClickListener for the Check Feed ID Dialog's OK-Button.
     * 
     * @author saschak.
     */
    private final class OkOnClickListener implements
	    DialogInterface.OnClickListener
    {
	public void onClick(DialogInterface dialog, int which)
	{
	    manageWorkflow();
	}
    }

    // ***************************************************************************
    // Menu

    @Override
    public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu)
    {
	menu.add(0, SETTINGS, 0, "Settings")
		.setIcon(R.drawable.ic_action_settings)
		.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);

	return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(
	    com.actionbarsherlock.view.MenuItem item)
    {
	switch (item.getItemId())
	{
	case SETTINGS:
	    startSettingsActivity();
	    break;

	default:
	    break;
	}

	return super.onOptionsItemSelected(item);
    }

    /**
     * Starts the SettingsActivity.
     */
    public void startSettingsActivity()
    {
	if (isTracking())
	{
	    // In case the device is tracking don't allow opening the
	    // SettingsActivity and inform the user
	    Toast.makeText(ctx, R.string.noSettings, Toast.LENGTH_SHORT).show();
	}
	else
	{
	    // Open the SettingsActivity
	    startActivity(new Intent(ctx, SettingsActivity.class));
	}
    }

    // ***************************************************************************
    // Tracking status

    /**
     * Changes the button's appearance depending on the tracking status.
     */
    public void changeButtonLayout()
    {
	if (isTracking())
	{
	    startButton.setText(R.string.stop);
	    startButton.setBackgroundColor(getResources().getColor(
		    R.color.holo_red_light));
	}
	else
	{
	    startButton.setText(R.string.start);
	    startButton.setBackgroundColor(getResources().getColor(
		    R.color.holo_green_light));
	}
    }

    /**
     * Changes the tracking status and saves it in the SharedPreferences.
     */
    public void changeTrackingStatus()
    {
	if (!isTracking())
	{
	    editor.putBoolean(Store.TRACKING_STATUS, true);
	}
	else
	{
	    editor.putBoolean(Store.TRACKING_STATUS, false);
	}

	editor.commit();
    }

    /**
     * Returns the tracking status.
     * 
     * @return
     */
    public static boolean isTracking()
    {
	return prefs.getBoolean(Store.TRACKING_STATUS, false);
    }

    /**
     * Starts and stops the SensorService depending on the tracking status.
     */
    public void manageSensorService()
    {
	if (isTracking())
	{
	    startService(new Intent(ctx, IptSensorService.class));
	}
	else
	{
	    stopService(new Intent(ctx, IptSensorService.class));
	}
    }

    /**
     * Starts and stops the UploadService depending on the tracking status.
     */
    public void manageUploadService()
    {
	if (isTracking())
	{
	    startService(new Intent(ctx, IptUploadService.class));
	}
	else
	{
	    stopService(new Intent(ctx, IptUploadService.class));
	}
    }

    /**
     * Saves/resets the Feed ID.
     */
    public void saveFeedID()
    {
	if (isTracking())
	{
	    String currentFeedID = editText.getText().toString();

	    // Save the current feed ID from the EditText
	    editor.putString(Store.FEED_ID, currentFeedID);

	    // Save the current feed ID for uploading after tracking has stopped
	    // because the feed ID gets reset to "" after tracking has been
	    // stopped
	    editor.putString(Store.LAST_FEED_ID, currentFeedID);
	}
	else
	{
	    // Reset the feed ID to empty string ""
	    editor.putString(Store.FEED_ID, "");
	}

	editor.commit();
    }

    // ***************************************************************************
    // Workflow

    /**
     * Manages the app's tracking status related workflow. The
     * changeTrackingStatus() method must ALWAYS be the first called method
     * here!!!
     */
    public void manageWorkflow()
    {
	// Must be called before all other methods
	changeTrackingStatus();

	changeButtonLayout();

	saveFeedID();

	manageSensorService();

	manageUploadService();
    }
}